package api

import (
	"encoding/json"
	"net/http"
	"strconv"
	"time"

	"b2c-delivery-optimization/internal/model"
	"b2c-delivery-optimization/internal/services"

	"github.com/gin-gonic/gin"
)

// WaveHandler 波次管理API处理器
type WaveHandler struct {
	waveService *services.WaveService
}

// NewWaveHandler 创建波次管理API处理器
func NewWaveHandler(waveService *services.WaveService) *WaveHandler {
	return &WaveHandler{
		waveService: waveService,
	}
}

// CreateWave 创建新波次
// @Summary 创建新波次
// @Description 创建一个新的波次
// @Tags 波次管理
// @Accept json
// @Produce json
// @Param wave body model.Wave true "波次信息"
// @Success 200 {object} model.Wave
// @Router /api/v1/waves [post]
func (h *WaveHandler) CreateWave(c *gin.Context) {
	var wave model.Wave
	if err := c.ShouldBindJSON(&wave); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.waveService.CreateWave(&wave); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, wave)
}

// GetWave 获取波次详情
// @Summary 获取波次详情
// @Description 根据ID获取波次详细信息
// @Tags 波次管理
// @Accept json
// @Produce json
// @Param id path string true "波次ID"
// @Success 200 {object} model.Wave
// @Router /api/v1/waves/{id} [get]
func (h *WaveHandler) GetWave(c *gin.Context) {
	id := c.Param("id")
	wave, err := h.waveService.GetWave(id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Wave not found"})
		return
	}

	c.JSON(http.StatusOK, wave)
}

// ListWaves 列出波次
// @Summary 列出波次
// @Description 根据查询条件列出波次
// @Tags 波次管理
// @Accept json
// @Produce json
// @Param status query int false "波次状态"
// @Param delivery_station_id query string false "配送站ID"
// @Param start_time query string false "开始时间"
// @Param end_time query string false "结束时间"
// @Param priority query int false "优先级"
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Success 200 {object} model.WaveListResponse
// @Router /api/v1/waves [get]
func (h *WaveHandler) ListWaves(c *gin.Context) {
	query := &model.WaveQuery{
		Page:     1,
		PageSize: 10,
	}

	// 解析查询参数
	if status := c.Query("status"); status != "" {
		var s model.WaveStatus
		if err := json.Unmarshal([]byte(`"`+status+`"`), &s); err == nil {
			query.Status = s
		}
	}

	query.DeliveryStationID = c.Query("delivery_station_id")

	if startTime := c.Query("start_time"); startTime != "" {
		if t, err := time.Parse(time.RFC3339, startTime); err == nil {
			query.StartTime = t
		}
	}

	if endTime := c.Query("end_time"); endTime != "" {
		if t, err := time.Parse(time.RFC3339, endTime); err == nil {
			query.EndTime = t
		}
	}

	if priority := c.Query("priority"); priority != "" {
		if p, err := strconv.Atoi(priority); err == nil {
			query.Priority = p
		}
	}

	if page := c.Query("page"); page != "" {
		if p, err := strconv.Atoi(page); err == nil {
			query.Page = p
		}
	}

	if pageSize := c.Query("page_size"); pageSize != "" {
		if ps, err := strconv.Atoi(pageSize); err == nil {
			query.PageSize = ps
		}
	}

	waves, total, err := h.waveService.ListWaves(query)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, model.WaveListResponse{
		Total: total,
		Items: waves,
	})
}

// UpdateWaveStatus 更新波次状态
// @Summary 更新波次状态
// @Description 更新波次的状态
// @Tags 波次管理
// @Accept json
// @Produce json
// @Param id path string true "波次ID"
// @Param status body model.WaveStatus true "新状态"
// @Success 200 {object} model.Wave
// @Router /api/v1/waves/{id}/status [put]
func (h *WaveHandler) UpdateWaveStatus(c *gin.Context) {
	id := c.Param("id")
	var status model.WaveStatus
	if err := c.ShouldBindJSON(&status); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 获取当前波次状态
	wave, err := h.waveService.GetWave(id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Wave not found"})
		return
	}

	// 验证状态转换是否合法
	if err := h.waveService.ValidateWaveStatus(wave.Status, status); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.waveService.UpdateWaveStatus(id, status); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 获取更新后的波次信息
	updatedWave, err := h.waveService.GetWave(id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, updatedWave)
}

// AddOrdersToWave 向波次添加订单
// @Summary 向波次添加订单
// @Description 向指定波次添加多个订单
// @Tags 波次管理
// @Accept json
// @Produce json
// @Param id path string true "波次ID"
// @Param order_ids body []string true "订单ID列表"
// @Success 200 {object} model.Wave
// @Router /api/v1/waves/{id}/orders [post]
func (h *WaveHandler) AddOrdersToWave(c *gin.Context) {
	id := c.Param("id")
	var orderIDs []string
	if err := c.ShouldBindJSON(&orderIDs); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.waveService.AddOrdersToWave(id, orderIDs); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 获取更新后的波次信息
	wave, err := h.waveService.GetWave(id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, wave)
}

// PredictReleaseTime 预测波次释放时间
// @Summary 预测波次释放时间
// @Description 预测指定波次的释放时间
// @Tags 波次管理
// @Accept json
// @Produce json
// @Param id path string true "波次ID"
// @Success 200 {object} model.PredictionResponse
// @Router /api/v1/waves/{id}/predict [get]
func (h *WaveHandler) PredictReleaseTime(c *gin.Context) {
	id := c.Param("id")
	predictedTime, err := h.waveService.PredictReleaseTime(id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, model.PredictionResponse{
		PredictedTime: predictedTime,
	})
}

// GetWaveOrders 获取波次中的订单
// @Summary 获取波次中的订单
// @Description 获取指定波次中的所有订单
// @Tags 波次管理
// @Accept json
// @Produce json
// @Param id path string true "波次ID"
// @Success 200 {array} model.Order
// @Router /api/v1/waves/{id}/orders [get]
func (h *WaveHandler) GetWaveOrders(c *gin.Context) {
	id := c.Param("id")
	orders, err := h.waveService.GetWaveOrders(id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, orders)
}

// AllocateOrdersToWaves 将订单分配到波次
// @Summary 将订单分配到波次
// @Description 将多个订单智能分配到波次中
// @Tags 波次管理
// @Accept json
// @Produce json
// @Param request body AllocateOrdersRequest true "分配请求参数"
// @Success 200 {object} gin.H
// @Router /api/v1/waves/allocate [post]
func (h *WaveHandler) AllocateOrdersToWaves(c *gin.Context) {
	var req AllocateOrdersRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 验证参数
	if len(req.OrderIDs) == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "订单ID列表不能为空"})
		return
	}
	if req.MaxOrdersPerWave <= 0 {
		req.MaxOrdersPerWave = 50 // 默认每个波次最多50个订单
	}

	// 调用服务进行分配
	if err := h.waveService.AllocateOrdersToWaves(req.OrderIDs, req.MaxOrdersPerWave); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "订单分配成功"})
}

// AllocateOrdersRequest 分配订单请求
type AllocateOrdersRequest struct {
	OrderIDs         []string `json:"order_ids" binding:"required"`  // 订单ID列表
	MaxOrdersPerWave int      `json:"max_orders_per_wave,omitempty"` // 每个波次最大订单数
}
